SYDE556/750 Assignment 4: Nengo and Dynamics

1) Building an ensemble of neurons

Make a new network, and inside that network make a group of neurons (in Nengo, this is called an "Ensemble" of neurons). It should have 100 neurons, and represent a 1-dimensional space. The intercepts should be between -1 and 1, and the maximum firing rates should be between 100Hz and 200Hz. $\tau_{RC}$ should be 0.02s and $\tau_{ref}$ should be 0.002s.

  • a) [1 mark] Show the "Constant Rate Responses" (the tuning curves) plot and the "Distortion" (representation accuracty) plot. These are accessed by right-clicking on the ensemble and choosing "Plot". Report the MSE (as indicated by the "Distortion" plot).
  • b) [1 mark] What happens to the MSE as the radius increases? Why? (Note: Nengo will automatically rescale the intercepts as the radius increases)
  • c) [0.5 marks] What happens to the MSE and the tuning curves as $\tau_{ref}$ changes? Why?
  • d) [0.5 marks] What happens to the MSE and the tuning curves as $\tau_{RC}$ changes? Why?

2) Connecting neurons

Make a second ensemble of neurons. It should have the same parameters as the first ensemble of neurons (from the first question), but have only 50 neurons in it. Connect the first ensemble to the second such that it computes the identity function, using a post-synaptic time constant of 0.01. Create an input that is a value of 1 for when $0.1<t<0.4$, and otherwise is zero.

  • To create the input using the drag-and-drop GUI, drag an input into the network, make sure it is 1-dimensional, click "Set functions", choose User-defined function, click "set", and put in 1*(x0>0.1)*(x0<0.4) as the Expression. (In this case, we are defining a function of time, and x0 is the current time).
  • To create the input using scripting, you can do net.make_input('input', lambda t: 1 if 0.1<t<0.4 else 0)
  • a) [1 mark] Start Interactive Plots mode (the button in the top-right that looks like a set of graphs). Show the input value and the decoded values from the two ensembles in three separate plots. Run the simulation for 0.5 seconds.
  • b) [1 mark] Make a new version of the model where instead of computing the identity function, it computes y=1-2*x. Show the same graphs as in part (a).
    • From the drag-and-drop GUI, do this by dragging in a new Origin, setting its output dimensions to 1, setting the function to be User-defined function, and setting its Expression to be 1-2*x0.
    • From scripting, do a net.connect() call where func=lambda x: 1-2*x[0]

3) Dynamics

Build a neural integrator. This consists of one ensemble, one input, a connection from the input to the ensemble, and a connection from the ensemble back to itself. The ensemble should have 200 neurons and the same parameters as in question 1. The post-synaptic time constant of the recurrent connection is 0.05, and the post-synaptic time constant of the input is 0.005.

To be an integrator, the desired dynamical system is ${dx} \over {dt} = u$. To implement this with the NEF, we use the transformation discussed in class that means that the feedback connection should compute $f'(x)=x$ and the input connection should compute $g'(x)=\tau u$ where $u$ is the input and $\tau$ is the post-synaptic time constant of the feedback connection. So the feedback connection should compute the identity function and the input connection should compute 0.05 times the input.

  • In the GUI, the scaling of 0.05 is most easily done when creating the Termination, as you can click on "set weights" and specify a weight of 0.05
  • In the scripting system, this is most easily done by setting weight=0.05 when making the input connection.

  • a) [1 mark] Using the interactive plots, show the input and the value represented by the ensemble when the input is a value of 0.9 from t=0.04 to t=1.0 (and 0 for other times). For this plot, the "time shown" setting should be 1.5 (click on the triangle at the bottom of the window to set this) and the simulation should be run for 1.5 seconds. What is the expected ideal result (i.e. if we just mathematically computed the integral of the input, what would we get?) How does this compare to that ideal?

  • b) [1 mark] Change the neural simulation to rate mode (by changing the mode to 'rate' from 'default'). Reset the simulation and re-run it in rate mode. Show the resulting plots. How does this compare to the result in part (a)?
  • c) [1 mark] Returning to spiking (default) mode, change the input to be a value of 0.9 from t=0.04 to 0.16. Show the same plots as before (the input and the value represented by the ensemble over 1.5 seconds). How does this compare to (a)? Why is it better or worse?
  • d) [1 mark] Change the input to a ramp input from 0 to 0.9 from t=0 to t=0.45 (and 0 for t>0.45). In the GUI, this is done with a User-defined function of 2*x0*(x0<0.45) and in the scripting this is done with net.make_input('input', lambda t: 2*t if t<0.45 else 0). Show the same plots as in the previous parts of this question. What does the ensemble end up representing, and why? What is the (ideal) equation for the curve traced out by the ensemble?
  • e) [1 mark] Change the input to 5*sin(5*t) (for specifying this in the GUI, this would be 5*sin(5*x0)). What should be the value represented by the ensemble (write the equation)? How well does it do? What are the differences between the model's behaviour and the expected ideal behaviour?